package org.pay.mch.settlement.ctrl;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.pay.core.common.Exception.ServiceException;
import org.pay.core.common.constant.Constant;
import org.pay.core.common.constant.MchConstant;
import org.pay.core.common.constant.RetEnum;
import org.pay.core.common.domain.BizResponse;
import org.pay.core.common.domain.PayPageRes;
import org.pay.core.common.domain.PayResponse;
import org.pay.core.common.util.FileUtils;
import org.pay.core.common.util.MD5Util;
import org.pay.core.common.util.MyLog;
import org.pay.core.entity.MchInfo;
import org.pay.core.entity.MchSettBatchRecord;
import org.pay.core.entity.MchSettRecord;
import org.pay.mch.common.ctrl.BaseController;
import org.pay.mch.common.service.RpcCommonService;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;

/**
 * @author: yangshancheng
 * @date: 17/12/6
 * @description:
 */
@RestController
@RequestMapping(Constant.MCH_CONTROLLER_ROOT_PATH + "/sett")
@PreAuthorize("hasRole('"+ MchConstant.MCH_ROLE_NORMAL+"')")
public class SettController extends BaseController {

    @Autowired
    private RpcCommonService rpcCommonService;

    private static final MyLog _log = MyLog.getLog(SettController.class);

    /**
     * 申请结算
     * @return
     */
    @RequestMapping("/apply")
    @ResponseBody
    public ResponseEntity<?> apply(HttpServletRequest request) {
        JSONObject param = getJsonParam(request);
        Long bankAccountId = getLongRequired(param, "bankAccountId");
        String settAmount = getStringRequired(param, "settAmount");         // 前端填写的为元,可以为小数点2位
        Long settAmountL = new BigDecimal(settAmount.trim()).multiply(new BigDecimal(100)).longValue(); // // 转成分
        String payPassword = getStringRequired(param, "payPassword");   // 支付密码
        String passwordMd5 = MD5Util.string2MD5(payPassword);
        // 判断输入支付密码是否正确
        MchInfo mchInfo = rpcCommonService.rpcMchInfoService.findByMchId(getUser().getId());
        if(!mchInfo.getPayPassword().equals(passwordMd5)) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_MCH_PAP_PASSWORD_NOT_MATCH));
        }
        // 发起提现申请
        try {
            int count = rpcCommonService.rpcMchSettHandleService.applySett(getUser().getId(), bankAccountId, settAmountL);
            if(count == 1) return ResponseEntity.ok(BizResponse.buildSuccess());
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_COMM_OPERATION_FAIL));
        }catch (ServiceException e) {
            return ResponseEntity.ok(BizResponse.build(e.getRetEnum()));
        }catch (Exception e) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_COMM_UNKNOWN_ERROR));
        }
    }

    /**
     * 上传csv账户信息
     * @param request
     * @param csvFile
     * @return
     */
    @RequestMapping("/csv_upload")
    public Object uploadExcel(HttpServletRequest request, @RequestParam(value = "csvFile", required = true) MultipartFile csvFile){
        Long startTime = System.currentTimeMillis();
        JSONObject param = getJsonParam(request);
        Long settRecordId = getLongRequired(param, "id");   // 结算记录ID
        if(csvFile.isEmpty()) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_COMM_OPERATION_FAIL));
        }
        MchSettRecord settRecord = rpcCommonService.rpcMchSettHandleService.findByMchIdAndId(getUser().getId(), settRecordId);
        if(settRecord == null) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_SERVICE_SETT_RECORD_NOT_EXIST));
        }
        // 如果不是等待审核状态,则不允许提交
        if(settRecord.getSettStatus() != MchConstant.SETT_STATUS_AUDIT_ING) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_SERVICE_SETT_STATUS_ERROR));
        }
        try {
            InputStreamReader fr = new InputStreamReader(csvFile.getInputStream(), "GBK");
            List<List<String>> csvList = FileUtils.readCSVFile(fr, "GBK");
            List<MchSettBatchRecord> mchSettBatchRecords = new LinkedList<>();
            // 记录文件中总金额
            Long totalAmount= 0l;
            for(int i = 0; i < csvList.size(); i++) {
                List<String> strList = csvList.get(i);
                try {
                    if(i > 0 && StringUtils.isNotBlank(strList.get(0))) {
                        MchSettBatchRecord entity = new MchSettBatchRecord();
                        entity.setMchId(getUser().getId());
                        entity.setSettRecordId(settRecordId);
                        entity.setBankAccountName(strList.get(0).trim());   // 收款银行户名
                        entity.setBankAccountNumber(strList.get(1).trim()); // 收款银行账号
                        entity.setBankName(strList.get(2).trim());          // 开户银行
                        entity.setBankNetName(strList.get(3).trim());       // 开户网点名称
                        entity.setBankProvince(strList.get(4).trim());      // 开户行所在省
                        entity.setBankCity(strList.get(5).trim());          // 开户行所在市
                        Long amount = new BigDecimal(strList.get(6).trim()).multiply(new BigDecimal(100)).longValue();
                        entity.setAmount(amount);          // 金额(元转分)
                        entity.setPublicFlag(Byte.parseByte(strList.get(7).trim()));          // 对公私标识
                        totalAmount += amount;
                        mchSettBatchRecords.add(entity);
                    }
                }catch (Exception e) {
                    _log.error(e, "第" + i + "行数据处理异常");
                    return ResponseEntity.ok(BizResponse.build(RetEnum.RET_MCH_SETT_BATCH_APPLY_FORMAT_ERROR));
                }
            }
            // 如果账户记录为空
            if(mchSettBatchRecords.size() == 0) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.RET_MCH_SETT_BATCH_APPLY_EMPTY));
            }
            if((mchSettBatchRecords.size() > 1000)) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.RET_MCH_SETT_BATCH_APPLY_LIMIT));
            }
            // 文件中的金额与申请结算金额不符
            if(totalAmount.compareTo(settRecord.getSettAmount()) != 0) {
                return ResponseEntity.ok(BizResponse.build(RetEnum.RET_MCH_SETT_BATCH_APPLY_AMOUNT));
            }
            // 批量插入记录
            int batchInertCount = rpcCommonService.rpcMchSettBatchRecordService.insert(settRecordId, mchSettBatchRecords);
            JSONObject retObj = new JSONObject();
            retObj.put("batchInertCount", batchInertCount);
            retObj.put("totalAmount", totalAmount); //
            retObj.put("costTime", System.currentTimeMillis() - startTime); // 记录服务端耗时
            return ResponseEntity.ok(PayResponse.buildSuccess(retObj));
        } catch (IOException e) {
            return ResponseEntity.ok(BizResponse.build(RetEnum.RET_COMM_UNKNOWN_ERROR));
        }
    }

    /**
     * 批量账户记录查询
     * @return
     */
    @RequestMapping("/batch_record_list")
    @ResponseBody
    public ResponseEntity<?> batchRecordList(HttpServletRequest request) {
        JSONObject param = getJsonParam(request);
        Long settRecordId = getLongRequired(param, "id");   // 结算记录ID
        MchSettBatchRecord mchSettBatchRecord = new MchSettBatchRecord();
        mchSettBatchRecord.setMchId(getUser().getId());
        mchSettBatchRecord.setSettRecordId(settRecordId);
        int count = rpcCommonService.rpcMchSettBatchRecordService.count(mchSettBatchRecord);
        if(count == 0) ResponseEntity.ok(PayPageRes.buildSuccess());
        List<MchSettBatchRecord> mchSettBatchRecordList = rpcCommonService.rpcMchSettBatchRecordService.select((getPageIndex(param)-1) * getPageSize(param), getPageSize(param), mchSettBatchRecord);
        return ResponseEntity.ok(PayPageRes.buildSuccess(mchSettBatchRecordList, count));
    }

    /**
     * 结算列表查询
     * @return
     */
    @RequestMapping("/list")
    @ResponseBody
    public ResponseEntity<?> list(HttpServletRequest request) {
        JSONObject param = getJsonParam(request);
        MchSettRecord settRecord = getObject(param, MchSettRecord.class);
        if(settRecord == null) settRecord = new MchSettRecord();
        settRecord.setMchId(getUser().getId());
        int count = rpcCommonService.rpcMchSettHandleService.count(settRecord);
        if(count == 0) ResponseEntity.ok(PayPageRes.buildSuccess());
        List<MchSettRecord> mchSettRecordList = rpcCommonService.rpcMchSettHandleService.select((getPageIndex(param)-1) * getPageSize(param), getPageSize(param), settRecord);
        return ResponseEntity.ok(PayPageRes.buildSuccess(mchSettRecordList, count));
    }

    /**
     * 结算查询
     * @return
     */
    @RequestMapping("/get")
    @ResponseBody
    public ResponseEntity<?> get(HttpServletRequest request) {
        JSONObject param = getJsonParam(request);
        Long id = getLongRequired(param, "id");
        MchSettRecord settRecord = rpcCommonService.rpcMchSettHandleService.findByMchIdAndId(getUser().getId(), id);
        return ResponseEntity.ok(PayResponse.buildSuccess(settRecord));
    }
}
